@typeparam TItem
@using Radzen.Blazor.Rendering
@if (RowIndex == Column.GetLevel())
{
<th rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@GetStyle()" @onmouseup=@(args => Grid.EndColumnReorder(args, ColumnIndex))>
    <div @onclick='@((args) => Grid.OnSort(args, Column))' tabindex="@SortingTabIndex" @onkeydown="OnSortKeyPressed">
        @if ((Grid.AllowColumnReorder && Column.Reorderable || Grid.AllowGrouping && Column.Groupable))
        {
            <span id="@(Grid.getColumnUniqueId(ColumnIndex) + "-drag")" class="rz-column-drag"
                    @onclick:preventDefault="true" @onclick:stopPropagation="true"
                    @onmousedown:preventDefault="true"
                    @onmousedown=@(args => Grid.StartColumnReorder(args, ColumnIndex))></span>
        }
        <span class="rz-column-title" title="@(Grid.ShowColumnTitleAsTooltip ? @Column.GetTitle() : "")">
            @if (Column.HeaderTemplate != null)
            {
                <span class="rz-column-title-content">@Column.HeaderTemplate</span>
            }
            else
            {
                <span class="rz-column-title-content">@Column.GetTitle()</span>
            }

        @if (Grid.AllowSorting && Column.Sortable)
        {
            @if (Column.GetSortOrder() == SortOrder.Ascending)
            {
                <span class="rz-sortable-column-icon rzi-grid-sort rzi-sort rzi-sort-asc"></span>
                @if(Grid.ShowMultiColumnSortingIndex)
                {
                    <RadzenBadge BadgeStyle="BadgeStyle.Info" Shade="Shade.Lighter" IsPill=true Text="@Column.getSortIndexAsString()" />
                }
            }
            else if (Column.GetSortOrder() == SortOrder.Descending)
            {
                <span class="rz-sortable-column-icon rzi-grid-sort rzi-sort rzi-sort-desc"></span>
                @if(Grid.ShowMultiColumnSortingIndex)
                {
                            <RadzenBadge BadgeStyle="BadgeStyle.Info" Shade="Shade.Lighter" IsPill=true Text="@Column.getSortIndexAsString()" />
                }
            }
            else
            {
                <span class="rz-sortable-column-icon rzi-grid-sort rzi-sort"></span>
            }
        }
        </span>
        @if (Grid.AllowColumnResize && Column.Resizable && Column.Parent == null)
        {
            <div id="@(Grid.getColumnUniqueId(ColumnIndex) + "-resizer")" style="cursor:col-resize;float:right;"
                    @onclick:preventDefault="true" @onclick:stopPropagation="true" class="rz-column-resizer"
                    @onmousedown:preventDefault="true"
                    @onmousedown=@(args => Grid.StartColumnResize(args, ColumnIndex))>&nbsp;</div>
        }
        @if (Grid.AllowFiltering && Column.Filterable && Grid.FilterMode == FilterMode.Advanced)
        {
                <i @ref=@filterButton @onclick:stopPropagation="true" @onmousedown=@ToggleFilter
                   class="@getFilterIconCss(Column)" onclick=@getFilterOpen() >
                   @Grid.FilterIcon
                </i>

                <Popup Lazy=@(Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand) @ref=popup id="@($"{getColumnPopupID()}")" class="rz-overlaypanel"
                    style="display:none;min-width:250px;" tabindex="0">
                        <div class="rz-overlaypanel-content">
                            @if (Column.FilterTemplate != null)
                            {
                                @Column.FilterTemplate(Column)
                            }
                            else
                            {
                                <form id="@($"{getColumnPopupID()}-form")" @onsubmit="@(args => ApplyFilter())" class="rz-grid-filter">
                                <RadzenLabel Text="@Grid.FilterText" class="rz-grid-filter-label" />
                                <RadzenDropDown @onclick:preventDefault="true" Data="@(Column.GetFilterOperators().Select(t => new { Value = Column.GetFilterOperatorText(t), Key = t }))" TextProperty="Value" ValueProperty="Key" TValue="FilterOperator" Value="@Column.GetFilterOperator()" Change="@(args => Column.SetFilterOperator((FilterOperator)args))" />
                                @if (Column.FilterValueTemplate != null)
                                {
                                    @Column.FilterValueTemplate(Column)
                                } 
                                else if (PropertyAccess.IsNullableEnum(Column.FilterPropertyType) || PropertyAccess.IsEnum(Column.FilterPropertyType))
                                {
                                    <RadzenDropDown AllowClear="false" AllowFiltering="false" TValue="@object"
                                                    Value=@Column.GetFilterValue() Multiple="false" Placeholder="@Grid.EnumFilterSelectText" TextProperty="Text" ValueProperty="Value" Data=@EnumExtensions.EnumAsKeyValuePair(Nullable.GetUnderlyingType(Column.FilterPropertyType) ?? Column.FilterPropertyType)
                                                    Change="@(args => Column.SetFilterValue(args))" />
                                }
                                else if (PropertyAccess.IsNumeric(Column.FilterPropertyType))
                                {
                                    @(Grid.DrawNumericFilter(Column, false))
                                }
                                else if (PropertyAccess.IsDate(Column.FilterPropertyType))
                                {
                                    <RadzenDatePicker TValue="@object" ShowTime="@Column.ShowTimeForDateTimeFilter()" ShowTimeOkButton="true" DateFormat="@Grid.getFilterDateFormat(Column)"
                                                      Value="@Column.GetFilterValue()" Change="@(args => Column.SetFilterValue(args.Value))" AllowInput=@(Grid.AllowFilterDateInput) />

                                }
                                else if (Column.FilterPropertyType == typeof(bool) || Column.FilterPropertyType == typeof(bool?))
                                {
                                    <RadzenCheckBox TriState="true" TValue="@object" Value="@Column.GetFilterValue()" Change="@(args => { Column.SetFilterValue(null); Column.SetFilterValue(args); Grid.SaveSettings(); InvokeAsync(() => Grid.Reload()); })" />
                                }
                                else
                                {
                                    <RadzenTextBox Value="@($"{Column.GetFilterValue()}")" Change="@(args => Column.SetFilterValue(args))" />
                                }

                                <RadzenDropDown @onclick:preventDefault="true" TextProperty="Text" ValueProperty="Value" Style="width: 90px"
                                        Data="@(Enum.GetValues(typeof(LogicalFilterOperator)).Cast<LogicalFilterOperator>().Select(t => new { Text = t == LogicalFilterOperator.And ? Grid.AndOperatorText : Grid.OrOperatorText, Value = t }))" TValue="LogicalFilterOperator" Value="@Column.LogicalFilterOperator" Change="@(args => Column.SetLogicalFilterOperator((LogicalFilterOperator)args))" />

                                <RadzenDropDown @onclick:preventDefault="true" Data="@(Column.GetFilterOperators().Select(t => new { Value = Column.GetFilterOperatorText(t), Key = t }))" TextProperty="Value" ValueProperty="Key" TValue="FilterOperator" Value="@Column.GetSecondFilterOperator()" Change="@(args => Column.SetSecondFilterOperator((FilterOperator)args))" />
                                @if (Column.SecondFilterValueTemplate != null)
                                {
                                    @Column.SecondFilterValueTemplate(Column)
                                } 
                                else if (PropertyAccess.IsNullableEnum(Column.FilterPropertyType) || PropertyAccess.IsEnum(Column.FilterPropertyType))
                                {
                                    <RadzenDropDown AllowClear="false" AllowFiltering="false" TValue="@object"
                                                    Value=@Column.GetSecondFilterValue() Multiple="false" Placeholder="@Grid.EnumFilterSelectText" TextProperty="Text" ValueProperty="Value" Data=@EnumExtensions.EnumAsKeyValuePair(Nullable.GetUnderlyingType(Column.FilterPropertyType) ?? Column.FilterPropertyType)
                                                    Change="@(args => Column.SetFilterValue(args,false))" />
                                }
                                else if (PropertyAccess.IsNumeric(Column.FilterPropertyType))
                                {
                                    @(Grid.DrawNumericFilter(Column, false, false))
                                }
                                else if (PropertyAccess.IsDate(Column.FilterPropertyType))
                                {
                                    <RadzenDatePicker TValue="@object"
                                                ShowTime="@Column.ShowTimeForDateTimeFilter()" ShowTimeOkButton="true" DateFormat="@Grid.getFilterDateFormat(Column)"
                                                      Value="@Column.GetSecondFilterValue()" Change="@(args => Column.SetFilterValue(args.Value, false))" AllowInput=@(Grid.AllowFilterDateInput) />

                                }
                                else if (Column.FilterPropertyType == typeof(bool) || Column.FilterPropertyType == typeof(bool?))
                                {
                                    <RadzenCheckBox TriState="true" TValue="@object" Value="@Column.GetSecondFilterValue()" Change="@(args => { Column.SetFilterValue(args, false); Grid.SaveSettings(); })" />
                                }
                                else
                                {
                                    <RadzenTextBox Value="@($"{Column.GetSecondFilterValue()}")" Change="@(args => Column.SetFilterValue(args, false))" />
                                }
                                </form>
                            }
                        </div>
                        @if (Column.FilterTemplate == null)
                        {
                            <div class="rz-grid-filter-buttons">
                                <RadzenButton ButtonStyle="ButtonStyle.Secondary" Text=@Grid.ClearFilterText Click="@ClearFilter" />
                                <RadzenButton form="@($"{getColumnPopupID()}-form")" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Primary" Text=@Grid.ApplyFilterText />
                            </div>
                        }
                    </Popup>
        }
    </div>
</th>
}
else
{
    @foreach(var column in Grid.childColumns.Where(c => c.GetVisible() && c.Parent == Column))
    {
        ColumnIndex = Grid.allColumns.IndexOf(column);//for child must have different columnindex

        <RadzenDataGridHeaderCell RowIndex="@RowIndex" Grid="@Grid" Column="@column" Style="@column.GetStyle(true, true)" ColumnIndex="@ColumnIndex"
            CssClass="@($" maitest rz-unselectable-text {(Grid.AllowSorting && column.Sortable ? "rz-sortable-column" : "")} {column.HeaderCssClass} {Grid.getFrozenColumnClass(column, Grid.ColumnsCollection.Where(c => c.GetVisible()).ToList())} {Grid.getCompositeCellCSSClass(column)} {Grid.getColumnAlignClass(column)}".Trim())" />
    }
}
@code {
    Radzen.Blazor.Rendering.Popup popup;
    ElementReference filterButton;

    string getFilterOpen()
    {
        return Grid.FilterPopupRenderMode == PopupRenderMode.Initial ? $"Radzen.togglePopup(this, '{getColumnPopupID()}')" : "";
    }

    async Task ToggleFilter()
    {
        if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
        {
            await popup.ToggleAsync(filterButton);
        }
    }

    async Task ClearFilter()
    {
        if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
        {
            await popup.CloseAsync();
        }
        await Grid.ClearFilter(Column, true);
    }

    async Task ApplyFilter()
    {
        if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
        {
            await popup.CloseAsync();
        }
        await Grid.ApplyFilter(Column, true);
    }

    [Parameter(CaptureUnmatchedValues = true)]
    public IReadOnlyDictionary<string, object> Attributes { get; set; }

    [Parameter]
    public RadzenDataGridColumn<TItem> Column { get; set; }

    [Parameter]
    public int ColumnIndex { get; set; }

    [Parameter]
    public int RowIndex { get; set; }

    [Parameter]
    public RadzenDataGrid<TItem> Grid { get; set; }

    [Parameter]
    public string CssClass { get; set; }

    [Parameter]
    public string Style { get; set; }

    private string GetStyle()
    {
        var styles = new List<string>() { Column.GetStyle(true, true), Style };

        if (Attributes?.TryGetValue("style", out var styleAttribute) == true)
        {
            styles.Add(Convert.ToString(styleAttribute));
        }

        var finalStyle = string.Join(";",
                styles
                .Select(x => x?.Trim().TrimEnd(';'))
                .Where(x => !string.IsNullOrEmpty(x))
            );

        return finalStyle;
    }

    private int SortingTabIndex => Grid.AllowSorting && Column.Sortable ? 0 : -1;

    private string getFilterIconCss(RadzenDataGridColumn<TItem> column)
    {
        var additionalStyle = column.GetFilterValue() != null || column.GetSecondFilterValue() != null ||
            column.GetFilterOperator() == FilterOperator.IsNotNull || column.GetFilterOperator() == FilterOperator.IsNull
                || column.GetFilterOperator() == FilterOperator.IsEmpty || column.GetFilterOperator() == FilterOperator.IsNotEmpty
                ? "rz-grid-filter-active" : "";
        return $"rzi rz-grid-filter-icon {additionalStyle}";
    }

    private void OnSortKeyPressed(KeyboardEventArgs args)
    {
        var key = args.Code ?? args.Key;
        if (key == "Enter")
        {
            Grid.OnSort(args, Column);
        }
    }

    string getColumnPopupID()
    {
        var fiterProperty = Column.GetFilterProperty();

        return $"{Grid.PopupID}{(string.IsNullOrEmpty(fiterProperty) ? Grid.allColumns.IndexOf(Column).ToString() : fiterProperty)}";
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();

        if (Column != null && Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
        {
            Column.headerCell = this;
        }
    }

    internal async Task CloseFilter()
    {
        if (popup != null)
        {
            await popup.CloseAsync(filterButton);
        }
    }
}
